home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2007 January, February, March & April
/
Chip-Cover-CD-2007-02.iso
/
Pakiet bezpieczenstwa
/
mini Pentoo LiveCD 2006.1
/
mpentoo-2006.1.iso
/
livecd.squashfs
/
usr
/
bin
/
euse
< prev
next >
Wrap
Text File
|
2006-05-08
|
12KB
|
413 lines
#!/bin/bash
# $Header$
# bash replacement for the original euse by Arun Bhanu
# Author: Marius Mauch <genone@gentoo.org>
# Version: 0.2
# Licensed under the GPL v2
PROGRAM_NAME=euse
PROGRAM_VERSION=0.1
MAKE_CONF_PATH=/etc/make.conf
MAKE_GLOBALS_PATH=/etc/make.globals
MAKE_PROFILE_PATH=/etc/make.profile
MAKE_CONF_BACKUP_PATH=/etc/make.conf.euse_backup
[ -z "${MODE}" ] && MODE="showhelp" # available operation modes: showhelp, showversion, showdesc, showflags, modify
parse_arguments() {
if [ -z "${1}" ]; then
return
fi
while [ -n "${1}" ]; do
case "${1}" in
-h | --help) MODE="showhelp";;
-v | --version) MODE="showversion";;
-i | --info) MODE="showdesc";;
-l | --local) SCOPE="local";;
-g | --global) SCOPE="global";;
-a | --active) MODE="showflags";;
-E | --enable) MODE="modify"; ACTION="add";;
-D | --disable) MODE="modify"; ACTION="remove";;
-P | --prune) MODE="modify"; ACTION="prune";;
-*)
echo "ERROR: unknown option ${1} specified."
echo
MODE="showhelp"
;;
*)
ARGUMENTS="${ARGUMENTS} ${1}"
;;
esac
shift
done
}
error() {
echo "ERROR: ${1}"
set +f
exit 1
}
check_sanity() {
# file permission tests
local descdir
descdir="$(get_portdir)/profiles"
[ ! -r "${MAKE_CONF_PATH}" ] && error "${MAKE_CONF_PATH} is not readable"
[ ! -r "${MAKE_GLOBALS_PATH}" ] && error "${MAKE_GLOBALS_PATH} is not readable"
[ ! -h "${MAKE_PROFILE_PATH}" ] && error "${MAKE_PROFILE_PATH} is not a symlink"
[ -z "$(get_portdir)" ] && error "\$PORTDIR couldn't be determined"
[ ! -d "${descdir}" ] && error "${descdir} does not exist or is not a directory"
[ ! -r "${descdir}/use.desc" ] && error "${descdir}/use.desc is not readable"
[ ! -r "${descdir}/use.local.desc" ] && error "${descdir}/use.local.desc is not readable"
[ ! -r "$(get_make_defaults)" ] && error "$(get_make_defaults) is not readable"
[ "${MODE}" == "modify" -a ! -w "${MAKE_CONF_PATH}" ] && error ""${MAKE_CONF_PATH}" is not writable"
}
showhelp() {
echo "${PROGRAM_NAME} v${PROGRAM_VERSION}"
echo
echo "Syntax: ${PROGRAM_NAME} <option> [suboptions] [useflaglist]"
echo
echo "Options: -h, --help - show this message"
echo " -v, --version - show version information"
echo " -i, --info - show descriptions for the given useflags"
echo " -g, --global - show only global use flags (suboption)"
echo " -l, --local - show only local use flags (suboption)"
echo " -a, --active - show currently active useflags and their origin"
echo " -E, --enable - enable the given useflags"
echo " -D, --disable - disable the given useflags"
echo " -P, --prune - remove all references to the given flags from"
echo " make.conf to revert to default settings"
echo
echo "Notes: ${PROGRAM_NAME} currently only works for global flags defined"
echo " in make.globals, make.defaults or make.conf, it doesn't handle"
echo " use.defaults, use.mask or package.use yet (see portage(5) for details on"
echo " these files). It also might have issues with cascaded profiles."
echo " If multiple options are specified only the last one will be used."
}
showversion() {
echo "${PROGRAM_NAME} v${PROGRAM_VERSION}"
echo "Written by Marius Mauch"
echo
echo "Copyright (C) 2004 Gentoo Foundation, Inc."
echo "This is free software; see the source for copying conditions."
}
# the following function creates a bash array ACTIVE_FLAGS that contains the
# global use flags, indexed by origin: 0: environment, 1: make.conf,
# 2: make.defaults, 3: make.globals
get_useflags() {
# only calculate once as calling emerge is painfully slow
[ -n "${USE_FLAGS_CALCULATED}" ] && return
# backup portdir so get_portdir() doesn't give false results later
portdir_backup="${PORTDIR}"
ACTIVE_FLAGS[0]="${USE}"
USE=""
source "${MAKE_CONF_PATH}"
ACTIVE_FLAGS[1]="${USE}"
USE=""
for x in $(get_all_make_defaults); do
source "${x}"
ACTIVE_FLAGS[2]="${ACTIVE_FLAGS[2]} ${USE}"
done
USE=""
source "${MAKE_GLOBALS_PATH}"
ACTIVE_FLAGS[3]="${USE}"
# restore saved env variables
USE="${ACTIVE_FLAGS[0]}"
PORTDIR="${portdir_backup}"
# get the currently active USE flags as seen by portage, this has to be after
# restoring USE or portage won't see the original environment
ACTIVE_FLAGS[9]="$(emerge --info | grep 'USE=' | cut -b 5- | sed -e 's:"::g')" #'
USE_FLAGS_CALCULATED=1
}
# get the list of all known USE flags by reading use.desc and/or use.local.desc
# (depending on the value of $SCOPE)
get_useflaglist() {
local descdir
descdir="$(get_portdir)/profiles"
if [ -z "${SCOPE}" -o "${SCOPE}" == "global" ]; then
egrep "^[^# ]+ +-" "${descdir}/use.desc" | cut -d\ -f 1
fi
if [ -z "${SCOPE}" -o "${SCOPE}" == "local" ]; then
egrep "^[^# :]+:[^ ]+ +-" "${descdir}/use.local.desc" | cut -d: -f 2 | cut -d\ -f 1
fi
}
# get all make.defaults by traversing the cascaded profile directories
get_all_make_defaults() {
local curdir
local parent
local rvalue
curdir="$(readlink -f ${MAKE_PROFILE_PATH})"
while [ -f "${curdir}/parent" ]; do
[ -f "${curdir}/make.defaults" ] && rvalue="${curdir}/make.defaults ${rvalue}"
parent="$(egrep -v '(^#|^ *$)' ${curdir}/parent)"
curdir="$(readlink -f ${curdir}/${parent})"
done
echo "${rvalue}"
}
# get the path to make.defaults by traversing the cascaded profile directories
get_make_defaults() {
local curdir
local parent
curdir="$(readlink -f ${MAKE_PROFILE_PATH})"
while [ ! -f "${curdir}/make.defaults" -a -f "${curdir}/parent" ]; do
parent="$(egrep -v '(^#|^ *$)' ${curdir}/parent)"
curdir="$(readlink -f ${curdir}/${parent})"
done
echo "${curdir}/make.defaults"
}
# little helper function to get the status of a given flag in one of the
# ACTIVE_FLAGS elements. Arguments are 1: flag to test, 2: index of ACTIVE_FLAGS,
# 3: echo value for positive (and as lowercase for negative) test result,
# 4 (optional): echo value for "missing" test result, defaults to blank
get_flagstatus_helper() {
if echo " ${ACTIVE_FLAGS[${2}]} " | grep " ${1} " > /dev/null; then
echo -n "${3}"
elif echo " ${ACTIVE_FLAGS[${2}]} " | grep " -${1} " > /dev/null; then
echo -n "$(echo ${3} | tr [[:upper:]] [[:lower:]])"
else
echo -n "${4:- }"
fi
}
# prints a status string for the given flag, each column indicating the presence
# for portage, in the environment, in make.conf, in make.defaults and in make.globals.
# full positive value would be "[+ECDG]", full negative value would be [-ecdg],
# full missing value would be "[- ]" (portage only sees present or not present)
get_flagstatus() {
get_useflags
echo -n '['
get_flagstatus_helper "${1}" 9 "+" "-"
get_flagstatus_helper "${1}" 0 "E"
get_flagstatus_helper "${1}" 1 "C"
get_flagstatus_helper "${1}" 2 "D"
get_flagstatus_helper "${1}" 3 "G"
echo -n '] '
}
# faster replacement to `portageq portdir`
get_portdir() {
if [ -z "${PORTDIR}" ]; then
use_backup="${USE}"
source "${MAKE_GLOBALS_PATH}"
for x in $(get_all_make_defaults); do
source "${x}"
done
source "${MAKE_CONF_PATH}"
USE="${use_backup}"
fi
echo "${PORTDIR}"
}
# This function takes a list of use flags and shows the status and
# the description for each one, honoring $SCOPE
showdesc() {
local descdir
local current_desc
local found_one
local args
args="${*:-*}"
if [ -z "${SCOPE}" ]; then
SCOPE="global" showdesc ${args}
echo
SCOPE="local" showdesc ${args}
return
fi
descdir="$(get_portdir)/profiles"
[ "${SCOPE}" == "global" ] && echo "global use flags (searching: ${args})"
[ "${SCOPE}" == "local" ] && echo "local use flags (searching: ${args})"
echo "************************************************************"
if [ "${args}" == "*" ]; then
args="$(get_useflaglist | sort -u)"
fi
set ${args}
foundone=0
while [ -n "${1}" ]; do
if [ "${SCOPE}" == "global" ]; then
if grep "^${1} *-" "${descdir}/use.desc" > /dev/null; then
get_flagstatus "${1}"
foundone=1
fi
grep "^${1} *-" "${descdir}/use.desc"
fi
# local flags are a bit more complicated as there can be multiple
# entries per flag and we can't pipe into printf
if [ "${SCOPE}" == "local" ]; then
if grep ":${1} *-" "${descdir}/use.local.desc" > /dev/null; then
foundone=1
fi
grep ":${1} *-" "${descdir}/use.local.desc" \
| sed -e "s/^\([^:]\+\):\(${1}\) *- *\(.\+\)/\1|\2|\3/g" \
| while read line; do
pkg="$(echo $line | cut -d\| -f 1)"
flag="$(echo $line | cut -d\| -f 2)"
desc="$(echo $line | cut -d\| -f 3)"
get_flagstatus "${flag}"
printf "%s (%s):\n%s\n\n" "${flag}" "${pkg}" "${desc}"
done
fi
shift
done
if [ ${foundone} == 0 ]; then
echo "no matching entries found"
fi
}
# show a list of all currently active flags and where they are activated
showflags() {
local args
get_useflags
args="${*:-*}"
if [ "${args}" == "*" ]; then
args="$(get_useflaglist | sort -u)"
fi
set ${args}
while [ -n "${1}" ]; do
if echo " ${ACTIVE_FLAGS[9]} " | grep " ${1} " > /dev/null; then
printf "%-20s" ${1}
get_flagstatus ${1}
echo
fi
shift
done
}
# two small helpers to add or remove a flag from a USE string
add_flag() {
NEW_MAKE_CONF_USE="${NEW_MAKE_CONF_USE} ${1}"
}
remove_flag() {
NEW_MAKE_CONF_USE="${NEW_MAKE_CONF_USE// ${1} / }"
}
# USE flag modification function. Mainly a loop with calls to add_flag and
# remove_flag to create a new USE string which is then inserted into make.conf.
modify() {
if [ -z "${*}" ]; then
if [ "${ACTION}" != "prune" ]; then
echo "WARNING: no USE flags listed for modification, do you really"
echo " want to ${ACTION} *all* known USE flags?"
echo " If you don't please press Ctrl-C NOW!!!"
sleep 5
set $(get_useflaglist | sort -u)
fi
fi
get_useflags
NEW_MAKE_CONF_USE=" ${ACTIVE_FLAGS[1]} "
while [ -n "${1}" ]; do
if [ "${ACTION}" == "add" ]; then
if echo " ${NEW_MAKE_CONF_USE} " | grep " ${1} " > /dev/null; then
shift
elif echo " ${NEW_MAKE_CONF_USE} " | grep " -${1} " > /dev/null; then
remove_flag "-${1}"
else
add_flag "${1}"
shift
fi
elif [ "${ACTION}" == "remove" ]; then
if echo " ${NEW_MAKE_CONF_USE} " | grep " -${1} " > /dev/null; then
shift
elif echo " ${NEW_MAKE_CONF_USE} " | grep " ${1} " > /dev/null; then
remove_flag "${1}"
else
add_flag "-${1}"
shift
fi
elif [ "${ACTION}" == "prune" ]; then
if echo " ${NEW_MAKE_CONF_USE} " | grep " ${1} " > /dev/null; then
remove_flag "${1}"
elif echo " ${NEW_MAKE_CONF_USE} " | grep " -${1} " > /dev/null; then
remove_flag "-${1}"
fi
shift
fi
done
#echo "old flags:"
#echo ${ACTIVE_FLAGS[1]}
#echo
#echo "new flags:"
#echo ${NEW_MAKE_CONF_USE}
# a little loop to add linebreaks so we don't end with one ultra-long line
NEW_MAKE_CONF_USE_2=""
for x in ${NEW_MAKE_CONF_USE}; do
if [ $(((${#NEW_MAKE_CONF_USE_2}%70)+${#x}+2)) -gt 70 ]; then
NEW_MAKE_CONF_USE_2="${NEW_MAKE_CONF_USE_2}\\ \\n $x "
else
NEW_MAKE_CONF_USE_2="${NEW_MAKE_CONF_USE_2}${x} "
fi
done
# make a backup just in case the user doesn't like the new make.conf
cp -p "${MAKE_CONF_PATH}" "${MAKE_CONF_BACKUP_PATH}"
# as sed doesn't really work with multi-line patterns we have to replace USE
# on our own here. Basically just skip everything between USE=" and the
# closing ", printing our new USE line there instead.
inuse=0
(while read -r line; do
[ "${line:0:4}" == "USE=" ] && inuse=1
[ "${inuse}" == "0" ] && echo -E "${line}"
if [ "${inuse}" == "1" ] && echo "${line}" | egrep '" *(#.*)?$' > /dev/null; then
echo -n 'USE="'
echo -ne "${NEW_MAKE_CONF_USE_2%% }"
echo '"'
inuse=0
fi
done ) < "${MAKE_CONF_BACKUP_PATH}" | sed -e 's:\\ $:\\:' > "${MAKE_CONF_PATH}"
echo "${MAKE_CONF_PATH} was modified, a backup copy has been placed at ${MAKE_CONF_BACKUP_PATH}"
}
##### main program comes now #####
# disable globbing as it fucks up with args=*
set -f
parse_arguments "$@"
check_sanity
eval ${MODE} ${ARGUMENTS}
set +f